package com.zzyl.nursing.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.ai.AIModelInvoker;
import com.zzyl.common.exception.ServiceException;
import com.zzyl.nursing.domain.AiPrompt;
import com.zzyl.nursing.domain.HealthAssessment;
import com.zzyl.nursing.dto.HealthAssessmentDto;
import com.zzyl.nursing.mapper.HealthAssessmentMapper;
import com.zzyl.nursing.service.IHealthAssessmentService;
import com.zzyl.nursing.vo.health.HealthReportVo;
import com.zzyl.util.IDCardUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 健康评估Service业务层处理
 *
 * @author FuJiaWei
 * @date 2025-05-26
 */
@Slf4j
@Service
public class HealthAssessmentServiceImpl extends ServiceImpl<HealthAssessmentMapper, HealthAssessment> implements IHealthAssessmentService {
    @Autowired
    private HealthAssessmentMapper healthAssessmentMapper;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private AIModelInvoker aiModelInvoker;

    /**
     * 查询健康评估
     *
     * @param id 健康评估主键
     * @return 健康评估
     */
    @Override
    public HealthAssessment selectHealthAssessmentById(Long id) {
        return getById(id);
    }

    /**
     * 查询健康评估列表
     *
     * @param healthAssessment 健康评估
     * @return 健康评估
     */
    @Override
    public List<HealthAssessment> selectHealthAssessmentList(HealthAssessment healthAssessment) {
        return healthAssessmentMapper.selectHealthAssessmentList(healthAssessment);
    }

    /**
     * 新增健康评估
     *
     * @param healthAssessmentDto 健康评估
     * @return 结果
     */
    @Override
    public Long insertHealthAssessment(HealthAssessmentDto healthAssessmentDto) {
        //获取pdf内容
        String idCard = healthAssessmentDto.getIdCard();
        log.info("调用大模型评测：{}", idCard);
        String content = (String) redisTemplate.opsForHash().get("healthReport", idCard);
        if (StrUtil.isNotBlank(content)) {
            //查询后删除redis缓存的体检表
            redisTemplate.opsForHash().delete("healthReport", idCard);
            //调用大模型评估
            // 设计prompt提示词
            String prompt = StrUtil.format(AiPrompt.PROMPT, content);
            String result = aiModelInvoker.qianfanInvoker(prompt);
            log.info("智能评测的结果: {}, \r\n {}", idCard, result);
            if (StrUtil.isNotBlank(result)) {
                //解析返回的json字符串
                HealthReportVo healthReportVo = JSONUtil.toBean(result, HealthReportVo.class);
                //转成pojo对象
                HealthAssessment healthAssessment = getHealthAssessment(healthReportVo, healthAssessmentDto);
                //插入数据库
                save(healthAssessment);
                return healthAssessment.getId();
            }
        }
        throw new ServiceException("新增健康评估错误");
    }

    private HealthAssessment getHealthAssessment(HealthReportVo healthReportVo, HealthAssessmentDto healthAssessmentDto) {
        double HealthScore = healthReportVo.getHealthAssessment().getHealthIndex();
        HealthAssessment healthAssessment = BeanUtil.toBean(healthAssessmentDto, HealthAssessment.class);
        //出生日期
        healthAssessment.setBirthDate(IDCardUtils.getBirthDateByIdCard(healthAssessmentDto.getIdCard()));
        //年龄
        healthAssessment.setAge(IDCardUtils.getAgeByIdCard(healthAssessmentDto.getIdCard()));
        //性别(0:男，1:女)
        healthAssessment.setGender(IDCardUtils.getGenderFromIdCard(healthAssessmentDto.getIdCard()));
        //健康评分
        healthAssessment.setHealthScore(String.valueOf(HealthScore));
        //危险等级(健康, 提示, 风险, 危险, 严重危险)
        healthAssessment.setRiskLevel(healthReportVo.getHealthAssessment().getRiskLevel());
        //是否建议入住(0:建议，1:不建议)
        healthAssessment.setSuggestionForAdmission(getSuggestionForAdmission(HealthScore));
        //推荐护理等级
        healthAssessment.setNursingLevelName(getNursingLevelName(HealthScore));
        //入住情况(0:已入住，1:未入住)
        healthAssessment.setAdmissionStatus(1);
        //总检日期
        healthAssessment.setTotalCheckDate(healthReportVo.getTotalCheckDate());
        //评估时间
        healthAssessment.setAssessmentTime(LocalDateTime.now());
        //报告总结
        healthAssessment.setReportSummary(healthReportVo.getSummarize());
        //疾病风险
        healthAssessment.setDiseaseRisk(JSONUtil.toJsonStr(healthReportVo.getRiskDistribution()));
        //异常分析
        healthAssessment.setAbnormalAnalysis(JSONUtil.toJsonStr(healthReportVo.getAbnormalData()));
        //健康系统分值
        healthAssessment.setSystemScore(JSONUtil.toJsonStr(healthReportVo.getSystemScore()));
        return healthAssessment;
    }

    /**
     * 计算护理等级
     */
    private String getNursingLevelName(double healthScore) {
        // 处理边界
        if (healthScore < 0 || healthScore > 100) {
            throw new IllegalArgumentException("健康评分必须在0到100之间");
        }

        if (healthScore >= 60 && healthScore < 70) {
            return "三级护理等级";
        } else if (healthScore >= 70 && healthScore < 80) {
            return "二级护理等级";
        } else if (healthScore >= 80 && healthScore < 90) {
            return "一级护理等级";
        } else if (healthScore >= 90) {
            return "特级护理等级";
        }
        return "无";

    }

    /**
     * 是否建议入住
     */
    private Integer getSuggestionForAdmission(double HealthScore) {
        if (HealthScore >= 60) {
            return 0;
        }
        return 1;
    }

    /**
     * 修改健康评估
     *
     * @param healthAssessment 健康评估
     * @return 结果
     */
    @Override
    public int updateHealthAssessment(HealthAssessment healthAssessment) {
        return updateById(healthAssessment) ? 1 : 0;
    }

    /**
     * 批量删除健康评估
     *
     * @param ids 需要删除的健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除健康评估信息
     *
     * @param id 健康评估主键
     * @return 结果
     */
    @Override
    public int deleteHealthAssessmentById(Long id) {
        return removeById(id) ? 1 : 0;
    }
}
